package Viewer;

import java.awt.BorderLayout;
import java.awt.Cursor;
import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.File;
import java.io.IOException;

import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JFileChooser;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.table.DefaultTableModel;

import sun.java2d.Disposer;

import Export.FetchNCBI;

/**
 * The track table manages all data import and removement.<br>
 * It contains a table where every row represents a track.<br>
 * All data formats are handled the same way and they are<br>
 * independent from each other, which means that features<br>
 * of different loci can load together in the browser.
 * 
 * @author Stefan Lorenz<br>
 * <br>
 *         29.11.2012
 */
@SuppressWarnings("serial")
public class TrackTable extends JTable {

	/**
	 * Viewer of the GeneScapes session
	 */
	private Viewer viewer;
	/**
	 * Window where the table is embedded
	 */
	private JFrame window;
	/**
	 * The track table
	 */
	private JTable table;
	/**
	 * The table model
	 */
	private DefaultTableModel model;
	/**
	 * Scrollpane for scrollable table
	 */
	private JScrollPane scrollPanel;

	/**
	 * Constructor of the track table which manages all data imports and unloads
	 * 
	 * @param viewer
	 *            viewer of the GeneScapes session
	 */
	public TrackTable(Viewer viewer) {
		this.viewer = viewer;
		this.window = new JFrame();
		this.window.setTitle("Track Table");
		this.window.setIconImage(new ImageIcon(InformationWindow.class.getResource("../resources/track32.png")).getImage());
		this.window.setResizable(false);
		this.window.setLayout(new BorderLayout());
		this.model = new DefaultTableModel();
		this.table = new JTable();
		this.window.setPreferredSize(new Dimension(500, 355));
		this.scrollPanel = new JScrollPane(this.table);
		this.window.add(this.scrollPanel);
		fillTable();
		addButtons();
		this.window.setLocationRelativeTo(viewer);
		this.window.setVisible(true);
		this.window.pack();
	}

	/**
	 * Adds all buttons to the track table with their actions
	 */
	public void addButtons() {
		JButton remove = new JButton("Unload track");
		remove.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent arg0) {
				// gene modeling track
				if (table.getSelectedRow() == 0) {
					Object[] options = { "Yes!", "No!" };
					int n = JOptionPane.showOptionDialog(viewer, "Do you really want to remove your gene model?", "Remove", JOptionPane.YES_NO_OPTION, JOptionPane.QUESTION_MESSAGE, null, options, options[0]);
					if (n == 0) {
						viewer.newAnnotatedGenome();
						viewer.getNewGenome().getListOfLoci().get(0).setLocusName(viewer.getNewAnnotationGenome().getName());
						viewer.getNewGenome().getListOfLoci().get(0).setLocusSize(viewer.getNewAnnotationGenome().getListOfLoci().get(0).getLocusSize());
						viewer.getNewGenome().getListOfLoci().get(0).setNameOfOrganism(viewer.getNewAnnotationGenome().getName());
					}
				}
				// all other tracks
				else {
					viewer.getLoadedTracks()[table.getSelectedRow()] = null;
				}
				fillTable();
				viewer.writeLastLoadedFiles(true);
				viewer.getDrawPanel().repaint();
			}
		});

		JButton addLocal = new JButton("Load local file...");
		addLocal.addActionListener(new ActionListener() {

			public void actionPerformed(ActionEvent arg0) {
				if (table.getSelectedRow() == -1) {
					JOptionPane.showMessageDialog(viewer, "Select track.", "No track selected", JOptionPane.WARNING_MESSAGE);
				}

				else if (table.getSelectedRow() == 0) {
					Object[] options = { "Yes!", "No!" };
					int n = JOptionPane.showOptionDialog(viewer, "Do you really want to load new data? Created gene model gets lost!", "Create new gene model", JOptionPane.YES_NO_OPTION, JOptionPane.QUESTION_MESSAGE, null, options, options[0]);
					if (n == 0) {
						if (viewer.getFileChooser().showOpenDialog(viewer) == JFileChooser.APPROVE_OPTION) {
							try {
								ReferenceChooser referenceChooser = new ReferenceChooser(viewer.getFileChooser().getSelectedFile());
								if(referenceChooser.isLoadable()){
									viewer.addTracks(viewer.getFileChooser().getSelectedFile(), 0,referenceChooser.getReference(),referenceChooser.getRange());
									fillTable();
								}
							} catch (IOException e) {
								e.printStackTrace();
							}

						} else {
							System.err.println("No Selection ");
						}
					}

				} else {
					if (viewer.getFileChooser().showOpenDialog(viewer) == JFileChooser.APPROVE_OPTION) {
						try {
							ReferenceChooser referenceChooser = new ReferenceChooser(viewer.getFileChooser().getSelectedFile());
							if(referenceChooser.isLoadable()){
								viewer.addTracks(viewer.getFileChooser().getSelectedFile(), table.getSelectedRow(),referenceChooser.getReference(),referenceChooser.getRange());
								fillTable();
							}
						} catch (IOException e) {
							e.printStackTrace();
						}
					} else {
						System.err.println("No Selection ");
					}
				}
			}
		});

		JButton genbankID = new JButton("Download from NCBI...");
		genbankID.addActionListener(new ActionListener() {

			public void actionPerformed(ActionEvent arg0) {
				if (table.getSelectedRow() == -1) {
					// no row selected to load track in
					JOptionPane.showMessageDialog(viewer, "Select row to load track.", "No row selected", JOptionPane.WARNING_MESSAGE);
				} else if (table.getSelectedRow() == 0) {
					Object[] options = { "Yes!", "No!" };
					int n = JOptionPane.showOptionDialog(viewer, "Do you really want to load data? All created annotations get lost!", "Create new list of annotations", JOptionPane.YES_NO_OPTION, JOptionPane.QUESTION_MESSAGE, null, options,
							options[0]);

					if (n == 0) {
						if (viewer.getFileChooser().showOpenDialog(viewer) == JFileChooser.APPROVE_OPTION) {
							try {
								ReferenceChooser referenceChooser = new ReferenceChooser(viewer.getFileChooser().getSelectedFile());
								if(referenceChooser.isLoadable()){
									viewer.addTracks(viewer.getFileChooser().getSelectedFile(), 0,referenceChooser.getReference(),referenceChooser.getRange());
									fillTable();
								}
							} catch (IOException e) {
								e.printStackTrace();
							}
						} else {
							System.err.println("No Selection ");
						}
					}
				} else if (table.getSelectedRow() == 1) {
					JOptionPane.showMessageDialog(viewer, "You can not load data into this track!", "Information", JOptionPane.WARNING_MESSAGE);
				} else {
					@SuppressWarnings("static-access")
					String id = new JOptionPane().showInputDialog(viewer, "Enter accession ID");
					if (id == null)
						return;
					try {
						setCursor(new Cursor(Cursor.WAIT_CURSOR));
						if (!new File("genomes/" + id + ".gbk").exists()) {
							System.out.println("...downloading " + id + ".gbk");
							new FetchNCBI(id, new File("genomes/" + id + ".gbk"));
						}
						if (new File("genomes/" + id + ".gbk").exists()) {
							System.out.println("...starting browser");
							ReferenceChooser referenceChooser = new ReferenceChooser(new File("genomes/" + id + ".gbk"));
							if(referenceChooser.isLoadable()){
								viewer.addTracks(new File("genomes/" + id + ".gbk"), table.getSelectedRow(),referenceChooser.getReference(),referenceChooser.getRange());
								fillTable();
							}
					
						} else
							System.err.println("Can not find file....downloading error?! Check you genome directory!");
					} catch (IOException e) {
						e.printStackTrace();
					}
				}
			}
		});
		JPanel buttonPanel = new JPanel();
		buttonPanel.add(addLocal);
		buttonPanel.add(genbankID);
		buttonPanel.add(remove);
		this.window.add(buttonPanel, BorderLayout.SOUTH);

	}

	/**
	 * Fills the track table with information about loaded files
	 */
	public void fillTable() {

		String[] columnNames = { "Index", "Name", "Type", "#Features" };
		int count = 16;
		Object[][] tempdata = new Object[count][4];

		tempdata[0][0] = 0;
		tempdata[0][2] = "gbk";
		tempdata[0][1] = "ABC-Track";
		tempdata[0][3] = this.viewer.getNewAnnotationList().size();

		for (int i = 1; i < count; i++) {
			try {
				tempdata[i][0] = i;
				tempdata[i][1] = this.viewer.getLoadedTracks()[i].getName();
				tempdata[i][2] = this.viewer.getLoadedTracks()[i].getTypeOfFile();
				tempdata[i][3] = this.viewer.getLoadedTracks()[i].getElementsOfTrack();
			} catch (NullPointerException e) {
			}
		}
		this.model = new DefaultTableModel(tempdata, columnNames);
		this.model.fireTableDataChanged();
		this.table.setModel(this.model);
		this.window.remove(this.scrollPanel);
		this.scrollPanel = new JScrollPane(this.table);
		this.window.add(this.scrollPanel);
		this.window.pack();
		this.viewer.getDrawPanel().repaint();

	}

	/**
	 * Sets window
	 * 
	 * @param window
	 *            jframe to set
	 */
	public void setWindow(JFrame window) {
		this.window = window;
	}

	/**
	 * Returns the jframe of the track table
	 * 
	 * @return the jframe of the track table
	 */
	public JFrame getWindow() {
		return window;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see javax.swing.JTable#isCellEditable(int, int)
	 */
	public boolean isCellEditable(int x, int y) {
		return false;
	}
	
	/**
	 * Closes the Jframe 
	 */
	public void dispose(){
		this.window.dispose();
	}
}